/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-10
 * V4.0
 */
package com.jphenix.clazz;

import com.jphenix.standard.docs.ClassInfo;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * <code>exception_table[]</code> of <code>Code_attribute</code>.
 * @author mabg
 */
@ClassInfo({"2014-06-10 19:55","exception_table"})
public class ExceptionTable implements Cloneable {
    
    private ArrayList<ExceptionTableEntry> entries;

    
    
    class ExceptionTableEntry {
        int startPc;
        int endPc;
        int handlerPc;
        int catchType;

        ExceptionTableEntry(int start, int end, int handle, int type) {
            startPc = start;
            endPc = end;
            handlerPc = handle;
            catchType = type;
        }
    }
    
    
    /**
     * Constructs an <code>exception_table[]</code>.
     *
     * @param cp        constant pool table.
     */
    public ExceptionTable(ConstPool cp) {
        entries = new ArrayList<ExceptionTableEntry>();
    }

    ExceptionTable(ConstPool cp, DataInputStream in) throws IOException {
        int length = in.readUnsignedShort();
        ArrayList<ExceptionTableEntry> list = new ArrayList<ExceptionTableEntry>(length);
        for (int i = 0; i < length; ++i) {
            int start = in.readUnsignedShort();
            int end = in.readUnsignedShort();
            int handle = in.readUnsignedShort();
            int type = in.readUnsignedShort();
            list.add(new ExceptionTableEntry(start, end, handle, type));
        }

        entries = list;
    }

    /**
     * Creates and returns a copy of this object.
     * The constant pool object is shared between this object
     * and the cloned object.
     */
    @Override
    public Object clone() throws CloneNotSupportedException {
        ExceptionTable r = (ExceptionTable)super.clone();
        r.entries = new ArrayList<ExceptionTableEntry>(entries);
        return r;
    }

    /**
     * Returns <code>exception_table_length</code>, which is the number
     * of entries in the <code>exception_table[]</code>.
     */
    public int size() {
        return entries.size();
    }

    /**
     * Returns <code>startPc</code> of the <i>n</i>-th entry.
     *
     * @param nth               the <i>n</i>-th (&gt;= 0).
     */
    public int startPc(int nth) {
        ExceptionTableEntry e = entries.get(nth);
        return e.startPc;
    }

    /**
     * Returns <code>endPc</code> of the <i>n</i>-th entry.
     *
     * @param nth               the <i>n</i>-th (&gt;= 0).
     */
    public int endPc(int nth) {
        ExceptionTableEntry e = entries.get(nth);
        return e.endPc;
    }


    /**
     * Returns <code>handlerPc</code> of the <i>n</i>-th entry.
     *
     * @param nth               the <i>n</i>-th (&gt;= 0).
     */
    public int handlerPc(int nth) {
        ExceptionTableEntry e = entries.get(nth);
        return e.handlerPc;
    }

    /**
     * Returns <code>catchType</code> of the <i>n</i>-th entry.
     *
     * @param nth               the <i>n</i>-th (&gt;= 0).
     * @return an index into the <code>constant_pool</code> table,
     *          or zero if this exception handler is for all exceptions.
     */
    public int catchType(int nth) {
        ExceptionTableEntry e = entries.get(nth);
        return e.catchType;
    }
}
